home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Draw / Sources / GroupShp.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  26.0 KB  |  864 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                GroupShp.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Author:                Mary Boetcher
  7. //
  8. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "ODFDraw.hpp"
  13.  
  14. #ifndef GROUPSHP_H
  15. #include "GroupShp.h"
  16. #endif
  17.  
  18. #ifndef DRAWPART_H
  19. #include "DrawPart.h"
  20. #endif
  21.  
  22. #ifndef DRAWCLIP_H
  23. #include "DrawClip.h"
  24. #endif
  25.  
  26. #ifndef UTILS_H
  27. #include "Utils.h"
  28. #endif
  29.  
  30. #ifndef CONTENT_H
  31. #include "Content.h"
  32. #endif
  33.  
  34. // ----- Part Layer -----
  35.  
  36. #ifndef FWUTIL_H
  37. #include "FWUtil.h"
  38. #endif
  39.  
  40. // ----- OS Layer -----
  41.  
  42. #ifndef FWODGEOM_H
  43. #include "FWODGeom.h"
  44. #endif
  45.  
  46. #ifndef FWGRUTIL_H
  47. #include "FWGrUtil.h"
  48. #endif
  49.  
  50. #ifndef FWACQUIR_H
  51. #include "FWAcquir.h"
  52. #endif
  53.  
  54. #ifndef FWRECSHP_H
  55. #include "FWRecShp.h"
  56. #endif
  57.  
  58. // ----- OpenDoc Includes -----
  59.  
  60. #ifndef SOM_ODTransform_xh
  61. #include <Trnsform.xh>
  62. #endif
  63.  
  64. #ifdef __MRC__
  65. // This is to go around a bug in MRC. It doesn't seems to see the extern
  66. // in BaseShp.cpp
  67. FW_DEFINE_AUTO_TEMPLATE(FW_TRefCountedCollection, CBaseShape)
  68. FW_DEFINE_AUTO_TEMPLATE(FW_TRefCountedCollectionIterator, CBaseShape)
  69. #endif
  70.  
  71. //========================================================================================
  72. // Segmentation
  73. //========================================================================================
  74.  
  75. #ifdef FW_BUILD_MAC
  76. #pragma segment odfdrawshapes
  77. #endif
  78.  
  79. //========================================================================================
  80. // class CGroupShape
  81. //========================================================================================
  82.  
  83. FW_DEFINE_CLASS_M1(CGroupShape, CBaseShape)
  84. FW_DEFINE_AUTO(CGroupShape)
  85.  
  86. const FW_ClassTypeConstant LGroupShape = FW_TYPE_CONSTANT('s','h','g','p');
  87. FW_REGISTER_ARCHIVABLE_CLASS(LGroupShape, CGroupShape, CGroupShape::Read, 0, 0, CBaseShape::Write)
  88.  
  89. //----------------------------------------------------------------------------------------
  90. // CGroupShape::CGroupShape
  91. //----------------------------------------------------------------------------------------
  92.  
  93. CGroupShape::CGroupShape(CDrawPart* drawPart) :
  94.     CBaseShape(drawPart, 4, kGroupShape, kFrameOnly),
  95.     fShapeList(NULL)
  96. {
  97.     fShapeList = FW_NEW(CShapeCollection, ());
  98.     FW_END_CONSTRUCTOR
  99. }
  100.  
  101. //----------------------------------------------------------------------------------------
  102. // CGroupShape::CGroupShape
  103. //----------------------------------------------------------------------------------------
  104.  
  105. CGroupShape::CGroupShape(CDrawPart* drawPart, CShapeCollection* shapeList) :
  106.     CBaseShape(drawPart, 4, kGroupShape, kFrameOnly)
  107. {
  108.     fShapeList = FW_NEW(CShapeCollection, ());
  109.     CShapeCollectionIterator it(shapeList);
  110.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  111.     {
  112.         fShapeList->AddLast(shape);
  113.     }
  114.     FW_END_CONSTRUCTOR
  115. }
  116.  
  117. //----------------------------------------------------------------------------------------
  118. // CGroupShape::CGroupShape
  119. //----------------------------------------------------------------------------------------
  120.  
  121. CGroupShape::CGroupShape(CDrawPart* drawPart, FW_CReadableStream& archive) :
  122.     CBaseShape(drawPart, archive)
  123. {
  124.     fShapeList = FW_NEW(CShapeCollection, ());
  125.     FW_END_CONSTRUCTOR
  126. }
  127.  
  128. //----------------------------------------------------------------------------------------
  129. // CGroupShape destructor
  130. //----------------------------------------------------------------------------------------
  131.  
  132. CGroupShape::~CGroupShape()
  133. {
  134.     FW_START_DESTRUCTOR
  135.     delete fShapeList;
  136. }
  137.  
  138. //----------------------------------------------------------------------------------------
  139. // CGroupShape::EmptyShapes
  140. //----------------------------------------------------------------------------------------
  141.  
  142. void CGroupShape::EmptyShapes()
  143. {
  144.     if (fShapeList)
  145.     {
  146.         FW_SOMEnvironment ev;
  147.         
  148.         CBaseShape* shape;
  149.         while ((shape = fShapeList->First()) != NULL)
  150.         {
  151.             shape->Removed(ev);
  152.             fShapeList->RemoveAndRelease(shape); // releases it too.
  153.         }
  154.     }
  155. }
  156.  
  157. //----------------------------------------------------------------------------------------
  158. // CGroupShape::Read
  159. //----------------------------------------------------------------------------------------
  160.  
  161. void* CGroupShape::Read(FW_CReadableStream& stream, FW_ClassTypeConstant type)
  162. {
  163. FW_UNUSED(type);
  164.     // [HLX] This is a hack until I can register object with the archiver
  165.     CDrawReadableStream *drawArchive = (CDrawReadableStream*)&stream;
  166.     CGroupShape* groupShape = FW_NEW(CGroupShape, (drawArchive->GetDrawPart(), stream));
  167.  
  168.     // Read shapes from the stream and add them to the group
  169.     unsigned long count;
  170.     stream >> count;
  171.     for (short i = 0; i<count; i++)
  172.     {
  173.         CBaseShape* theShape = NULL;
  174.         FW_READ_DYNAMIC_OBJECT(stream, &theShape, CBaseShape);
  175.         FW_ASSERT(theShape);
  176.         
  177.         // ----- Add the shape to the group -----
  178.         groupShape->AddShape(theShape);
  179.         theShape->SetGroupedState(groupShape);
  180.         theShape->Release();
  181.     }
  182.  
  183.     return groupShape;
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. // CGroupShape::Flatten
  188. //----------------------------------------------------------------------------------------
  189.  
  190. void CGroupShape::Flatten(FW_CWritableStream& archive)
  191. {    
  192.     CBaseShape::Flatten(archive);
  193.  
  194.     unsigned long count = fShapeList->Count();
  195.     archive << count;
  196.  
  197.     // Write group shapes to the archive
  198.     CShapeCollectionIterator it(fShapeList);
  199.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  200.     {
  201.         FW_WRITE_DYNAMIC_OBJECT(archive, shape, CBaseShape);
  202.     }    
  203. }
  204.  
  205. //----------------------------------------------------------------------------------------
  206. // CGroupShape::CreateShapeOutline
  207. //----------------------------------------------------------------------------------------
  208.  
  209. ODShape* CGroupShape::CreateShapeOutline(Environment* ev)
  210. {
  211.     FW_CRect bounds = GetRectGeometry();
  212.  
  213.         // We don't acquire it because we return it
  214.     ODShape* outline = ::FW_NewODShape(ev, bounds);
  215.  
  216.     ::FW_OutlineODShape(ev, outline, GetPenSize());
  217.  
  218.     return outline;
  219. }
  220.  
  221. //----------------------------------------------------------------------------------------
  222. // CGroupShape::CalcClipShape
  223. //----------------------------------------------------------------------------------------
  224.  
  225. ODShape* CGroupShape::CalcClipShape(Environment* ev)
  226. {
  227.     FW_CAcquiredODShape clipShape = ::FW_NewODShape(ev);
  228.  
  229.     CShapeCollectionIterator it(fShapeList);
  230.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  231.     {
  232.         FW_CAcquiredODShape tempShape = shape->AcquireClipShape(ev);
  233.         clipShape->Union(ev, tempShape);                            
  234.     }
  235.     
  236.     return clipShape.Orphan();
  237. }
  238.  
  239. //----------------------------------------------------------------------------------------
  240. // CGroupShape::GetHandleCenter
  241. //----------------------------------------------------------------------------------------
  242.  
  243. void CGroupShape::GetHandleCenter(short whichHandle, FW_CPoint& center) const
  244. {    
  245.     FW_CRect bounds = GetRectGeometry();
  246.  
  247.     switch (whichHandle)
  248.     {
  249.         case kInTopLeftCorner:
  250.             center.x = bounds.left;
  251.             center.y = bounds.top;
  252.             break;
  253.         case kInTopRightCorner:
  254.             center.x = bounds.right;
  255.             center.y = bounds.top;
  256.             break;
  257.         case kInBottomLeftCorner:
  258.             center.x = bounds.left;
  259.             center.y = bounds.bottom;
  260.             break;
  261.         case kInBottomRightCorner:
  262.             center.x = bounds.right;
  263.             center.y = bounds.bottom;
  264.             break;
  265.     }
  266. }
  267.  
  268. //----------------------------------------------------------------------------------------
  269. // CGroupShape::GetMapRects
  270. //----------------------------------------------------------------------------------------
  271.  
  272. void CGroupShape::GetMapRects(short whichHandle, const FW_CPoint& mouseLoc,
  273.                               FW_CRect& srcRect, FW_CRect& dstRect)
  274. {
  275.     srcRect = GetRectGeometry();
  276.     dstRect = srcRect;
  277.     
  278.     switch (whichHandle)
  279.     {
  280.         case kInTopLeftCorner:
  281.             dstRect.left = mouseLoc.x;
  282.             dstRect.top = mouseLoc.y;
  283.             break;
  284.         case kInTopRightCorner:
  285.             dstRect.right = mouseLoc.x;
  286.             dstRect.top = mouseLoc.y;
  287.             break;
  288.         case kInBottomLeftCorner:
  289.             dstRect.left = mouseLoc.x;
  290.             dstRect.bottom = mouseLoc.y;
  291.             break;
  292.         case kInBottomRightCorner:
  293.             dstRect.right = mouseLoc.x;
  294.             dstRect.bottom = mouseLoc.y;
  295.             break;
  296.     }
  297. }
  298.  
  299. //----------------------------------------------------------------------------------------
  300. // CGroupShape::GetRectGeometry
  301. //----------------------------------------------------------------------------------------
  302. // [HLX] should be cached
  303.  
  304. FW_CRect CGroupShape::GetRectGeometry() const
  305. {
  306.     // Calculate the boundary rectangle for our shapes
  307.     FW_CRect rect = FW_kZeroRect;
  308.     if (fShapeList->Count() != 0)
  309.     {
  310.         FW_Boolean first = true;
  311.         FW_CRect tempRect;
  312.     
  313.         CShapeCollectionIterator it(fShapeList);
  314.         for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  315.         {
  316.             shape->GetDragRect(tempRect);
  317.             if (first)
  318.                 rect = tempRect;
  319.             else
  320.                 rect |= tempRect;
  321.             first = false;
  322.         }
  323.     }
  324.     return rect;
  325. }
  326.  
  327. //----------------------------------------------------------------------------------------
  328. // CGroupShape::HitTest
  329. //----------------------------------------------------------------------------------------
  330.  
  331. FW_Boolean CGroupShape::HitTest(Environment* ev, FW_CGraphicContext& gc, const FW_CMouseEvent& theMouseEvent) const
  332. {
  333.     // Perform HitTest on each shape in this group
  334.     CShapeCollectionIterator it(fShapeList);
  335.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  336.     {
  337.         if (shape->HitTest(ev, gc, theMouseEvent))
  338.             return true;
  339.     }
  340.  
  341.     return false;    
  342. }
  343.  
  344. //----------------------------------------------------------------------------------------
  345. // CGroupShape::MapShape
  346. //----------------------------------------------------------------------------------------
  347.  
  348. void CGroupShape::MapShape(Environment* ev, const FW_CRect& srcRect, const FW_CRect& dstRect)
  349. {
  350. #if 1
  351.     FW_CRect beforeRect = GetRectGeometry();
  352.     FW_CRect afterRect = beforeRect;
  353.     afterRect.Map(srcRect, dstRect);
  354.  
  355.     // Map each shape in this group
  356.     CShapeCollectionIterator it(fShapeList);
  357.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  358.     {
  359.         shape->MapShape(ev, beforeRect, afterRect);
  360.     }
  361. #else
  362.     // Map each shape in this group
  363.     CShapeCollectionIterator it(fShapeList);
  364.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  365.     {
  366.         shape->MapShape(ev, srcRect, dstRect);
  367.     }
  368. #endif
  369. }
  370.  
  371. //----------------------------------------------------------------------------------------
  372. // CGroupShape::OffsetShape
  373. //----------------------------------------------------------------------------------------
  374.  
  375. void CGroupShape::OffsetShape(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
  376. {
  377. //    CheckPromise(ev); [HLX] Do not call CheckPromise from OffsetShape or end up in a infinity loop
  378. //                        because externalize of a pict calls OffsetShape
  379.     ClearCache(ev);
  380.  
  381.     // Offset each shape in this group
  382.     CShapeCollectionIterator it(fShapeList);
  383.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  384.     {
  385.         shape->OffsetShape(ev, xDelta, yDelta);
  386.     }
  387. }
  388.  
  389. //----------------------------------------------------------------------------------------
  390. // CGroupShape::RenderShape
  391. //----------------------------------------------------------------------------------------
  392.  
  393. void CGroupShape::RenderShape(Environment* ev, ODFacet* facet, FW_CGraphicContext& gc)
  394. {    
  395.     // Render each shape in this group
  396.     CShapeCollectionIterator it(fShapeList);
  397.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  398.     {
  399.         if (facet != NULL || shape->GetShapeType() != kProxyShape)
  400.             shape->RenderShape(ev, facet, gc);
  401.     }
  402. }
  403.  
  404. //----------------------------------------------------------------------------------------
  405. // CGroupShape::ResizeFeedback
  406. //----------------------------------------------------------------------------------------
  407.  
  408. void CGroupShape::ResizeFeedback(FW_CGraphicContext& gc, const FW_CInk& ink, const FW_CStyle& style, 
  409.                                  short whichHandle, const FW_CPoint& mouseLoc)
  410. {
  411.     FW_CRect srcRect, dstRect;
  412.     GetMapRects(whichHandle, mouseLoc, srcRect, dstRect);
  413.     dstRect.Sort();
  414.     OutlineShape(gc, ink, style, dstRect);
  415. }
  416.  
  417. //----------------------------------------------------------------------------------------
  418. // CGroupShape::SetShapeGeometry
  419. //----------------------------------------------------------------------------------------
  420.  
  421. void CGroupShape::SetShapeGeometry(const FW_CPoint& anchorPoint, const FW_CPoint& currentPoint)
  422. {
  423.     FW_CRect rect = GetRectGeometry();
  424.  
  425.     if (anchorPoint.x < currentPoint.x)
  426.     {
  427.         rect.left = anchorPoint.x;
  428.         rect.right = currentPoint.x;
  429.     }
  430.     else
  431.     {
  432.         rect.left = currentPoint.x;
  433.         rect.right = anchorPoint.x;
  434.     }
  435.     
  436.     if (anchorPoint.y < currentPoint.y)
  437.     {
  438.         rect.top = anchorPoint.y;
  439.         rect.bottom = currentPoint.y;
  440.     }
  441.     else
  442.     {
  443.         rect.top = currentPoint.y;
  444.         rect.bottom = anchorPoint.y;
  445.     }
  446.  
  447.     /* How to change group shape's geometry? */
  448. }
  449.  
  450. //----------------------------------------------------------------------------------------
  451. // CGroupShape::OutlineShape
  452. //----------------------------------------------------------------------------------------
  453.  
  454. void CGroupShape::OutlineShape(FW_CGraphicContext& gc, const FW_CInk& ink, const FW_CStyle& style, const FW_CRect& rect)
  455. {
  456.     FW_CRect bounds(rect);
  457.     AdjustRectForPenSize(bounds, style.GetPenSize());
  458.     FW_CRectShape::RenderRect(gc,
  459.                               bounds,
  460.                               FW_kFrame,
  461.                               ink, style);
  462. }
  463.  
  464. //------------------------------------------------------------------------------
  465. //    CGroupShape::RestoreShape
  466. //------------------------------------------------------------------------------
  467.  
  468. void CGroupShape::RestoreShape(Environment* ev)
  469. {
  470.     CBaseShape::RestoreShape(ev);
  471.     
  472.     // Call RestoreShape on each shape in this group
  473.     CShapeCollectionIterator it(fShapeList);
  474.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  475.     {
  476.         shape->RestoreShape(ev);
  477.     }
  478. }
  479.  
  480. //----------------------------------------------------------------------------------------
  481. // CGroupShape::Removed
  482. //----------------------------------------------------------------------------------------
  483.  
  484. void CGroupShape::Removed(Environment* ev)
  485. {
  486.     CBaseShape::Removed(ev);
  487.     
  488.     // Call Removed on each shape in this group
  489.     CShapeCollectionIterator it(fShapeList);
  490.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  491.     {
  492.         shape->Removed(ev);
  493.     }
  494. }
  495.  
  496. //------------------------------------------------------------------------------
  497. //    CGroupShape::Deleted - the shape is going to be deleted
  498. //------------------------------------------------------------------------------
  499.  
  500. void CGroupShape::Deleted(Environment* ev)
  501. {
  502.     CBaseShape::Deleted(ev);
  503.     
  504.     // Call Deleted on each shape in this group
  505.     CShapeCollectionIterator it(fShapeList);
  506.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  507.     {
  508.         shape->Deleted(ev);
  509.     }
  510. }
  511.  
  512. //----------------------------------------------------------------------------------------
  513. // CGroupShape::SelectShape
  514. //----------------------------------------------------------------------------------------
  515.  
  516. void CGroupShape::SelectShape(Environment* ev, FW_Boolean state)
  517. {
  518.     CBaseShape::SelectShape(ev, state);
  519.     
  520.     // ----- Select all the shapes in this group ----
  521.     CShapeCollectionIterator it(fShapeList);
  522.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  523.     {
  524.         shape->SelectShape(ev, state);
  525.     }
  526. }
  527.  
  528. //----------------------------------------------------------------------------------------
  529. // CGroupShape::SubtractToWorkingClip
  530. //----------------------------------------------------------------------------------------
  531.  
  532. void CGroupShape::SubtractToWorkingClip(Environment* ev, 
  533.                                         CDrawFacetClipper* facetClipper, 
  534.                                         ODFacet* containingFacet, 
  535.                                         ODShape* workingClip,
  536.                                         ODShape* tempShape,
  537.                                         ODShape* limitShape)
  538. {
  539.     /* [MEB] kludge - prevent crash on copy/paste a group shape containing proxies */
  540.     if (CountProxyShapes(ev) != 0)
  541.     {
  542.         CBaseShape::SubtractToWorkingClip(ev, facetClipper, containingFacet, workingClip, tempShape, limitShape);
  543.         return;
  544.     }
  545.  
  546.     // Call SubtractToWorkingClip on each shape in this group
  547.     CShapeCollectionIterator it(fShapeList);
  548.     for (CBaseShape* shape = it.Last(); it.IsNotComplete(); shape = it.Previous())
  549.     {
  550.         shape->SubtractToWorkingClip(ev, facetClipper, containingFacet, workingClip, tempShape, limitShape);
  551.     }
  552. }
  553.  
  554. //----------------------------------------------------------------------------------------
  555. // CGroupShape::AddShape
  556. //----------------------------------------------------------------------------------------
  557.  
  558. void CGroupShape::AddShape(CBaseShape* shape)
  559. {
  560.     fShapeList->AddLast(shape);
  561. }
  562.  
  563. //----------------------------------------------------------------------------------------
  564. // CGroupShape::CountShapes
  565. //----------------------------------------------------------------------------------------
  566.  
  567. unsigned long CGroupShape::CountShapes() const
  568. {
  569.     return fShapeList->Count();
  570. }
  571.  
  572. //------------------------------------------------------------------------------
  573. //    CGroupShape::CountProxyShapes
  574. //------------------------------------------------------------------------------
  575.  
  576. unsigned long CGroupShape::CountProxyShapes(Environment* ev) const
  577. {
  578.     unsigned long count = 0;
  579.     
  580.     CShapeCollectionIterator it(fShapeList);
  581.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  582.     {
  583.         if (shape->GetShapeType() == kProxyShape)
  584.             count++;
  585.         else if (shape->GetShapeType() == kGroupShape)
  586.             count += ((CGroupShape*) shape)->CountProxyShapes(ev);    // recursive call
  587.     }
  588.     
  589.     return count;
  590. }
  591.  
  592. //----------------------------------------------------------------------------------------
  593. // CGroupShape::GetFirstShape
  594. //----------------------------------------------------------------------------------------
  595.  
  596. CBaseShape* CGroupShape::GetFirstShape() const
  597. {
  598.     return fShapeList->First();
  599. }
  600.  
  601. //----------------------------------------------------------------------------------------
  602. // CGroupShape::RemoveShapes
  603. //----------------------------------------------------------------------------------------
  604.  
  605. void CGroupShape::RemoveShapes()
  606. {
  607.     this->EmptyShapes();
  608. }
  609.  
  610. //----------------------------------------------------------------------------------------
  611. // CGroupShape::Remove1Shape
  612. //----------------------------------------------------------------------------------------
  613.  
  614. void CGroupShape::Remove1Shape(CBaseShape* shape)
  615. {
  616.     fShapeList->RemoveAndRelease(shape);
  617. }
  618.  
  619. //----------------------------------------------------------------------------------------
  620. // CGroupShape::ChangeFillColor
  621. //----------------------------------------------------------------------------------------
  622.  
  623. void CGroupShape::ChangeFillColor(Environment* ev, const FW_CColor& color)
  624. {
  625.     CBaseShape::ChangeFillColor(ev, color);
  626.  
  627.     CShapeCollectionIterator it(fShapeList);
  628.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  629.     {
  630.         shape->ChangeFillColor(ev, color);
  631.     }
  632. }
  633.  
  634. //----------------------------------------------------------------------------------------
  635. // CGroupShape::ChangeFrameColor
  636. //----------------------------------------------------------------------------------------
  637.  
  638. void CGroupShape::ChangeFrameColor(Environment* ev, const FW_CColor& color)
  639. {
  640.     CBaseShape::ChangeFrameColor(ev, color);
  641.  
  642.     CShapeCollectionIterator it(fShapeList);
  643.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  644.     {
  645.         shape->ChangeFrameColor(ev, color);
  646.     }
  647. }
  648.  
  649. //----------------------------------------------------------------------------------------
  650. // CGroupShape::ChangeFillPattern
  651. //----------------------------------------------------------------------------------------
  652.  
  653. void CGroupShape::ChangeFillPattern(Environment* ev, const FW_CPattern& pattern)
  654. {
  655.     CBaseShape::ChangeFillPattern(ev, pattern);
  656.  
  657.     CShapeCollectionIterator it(fShapeList);
  658.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  659.     {
  660.         shape->ChangeFillPattern(ev, pattern);
  661.     }
  662. }
  663.  
  664. //----------------------------------------------------------------------------------------
  665. // CGroupShape::ChangeFramePattern
  666. //----------------------------------------------------------------------------------------
  667.  
  668. void CGroupShape::ChangeFramePattern(Environment* ev, const FW_CPattern& pattern)
  669. {
  670.     CBaseShape::ChangeFramePattern(ev, pattern);
  671.  
  672.     CShapeCollectionIterator it(fShapeList);
  673.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  674.     {
  675.         shape->ChangeFramePattern(ev, pattern);
  676.     }
  677. }
  678.  
  679. //----------------------------------------------------------------------------------------
  680. // CGroupShape::ChangePenSize
  681. //----------------------------------------------------------------------------------------
  682.  
  683. void CGroupShape::ChangePenSize(Environment* ev, FW_Fixed newPenSize)
  684. {
  685.     CBaseShape::ChangePenSize(ev, newPenSize);
  686.  
  687.     CShapeCollectionIterator it(fShapeList);
  688.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  689.     {
  690.         shape->ChangePenSize(ev, newPenSize);
  691.     }
  692. }
  693.  
  694. //----------------------------------------------------------------------------------------
  695. // CGroupShape::ChangeRenderVerb
  696. //----------------------------------------------------------------------------------------
  697.  
  698. void CGroupShape::ChangeRenderVerb(Environment* ev, unsigned short renderVerb)
  699. {
  700.     CBaseShape::ChangeRenderVerb(ev, renderVerb);
  701.  
  702.     CShapeCollectionIterator it(fShapeList);
  703.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  704.     {
  705.         shape->ChangeRenderVerb(ev, renderVerb);
  706.     }
  707. }
  708.  
  709. //----------------------------------------------------------------------------------------
  710. // CGroupShape::MakePurgeable
  711. //----------------------------------------------------------------------------------------
  712.  
  713. void CGroupShape::MakePurgeable(Environment* ev, CDrawFrame* drawFrame, const FW_CRect& bounds)
  714. {
  715.     CShapeCollectionIterator it(fShapeList);
  716.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  717.     {
  718.         shape->MakePurgeable(ev, drawFrame, bounds);
  719.     }
  720. }
  721.  
  722. //----------------------------------------------------------------------------------------
  723. // CGroupShape::SetSubscribeLink
  724. //----------------------------------------------------------------------------------------
  725.  
  726. void CGroupShape::SetSubscribeLink(Environment* ev, CDrawSubscribeLink* subscribeLink)
  727. {
  728.     CBaseShape::SetSubscribeLink(ev, subscribeLink);
  729.  
  730.     CShapeCollectionIterator it(fShapeList);
  731.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  732.     {
  733.         shape->SetSubscribeLink(ev, subscribeLink);
  734.     }
  735. }
  736.  
  737. //----------------------------------------------------------------------------------------
  738. // CGroupShape::ShapeCommitPasteDone
  739. //----------------------------------------------------------------------------------------
  740.  
  741. void CGroupShape::ShapeCommitPasteDone(Environment* ev)
  742. {
  743.     CShapeCollectionIterator it(fShapeList);
  744.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  745.     {
  746.         shape->ShapeCommitPasteDone(ev);
  747.     }
  748. }
  749.  
  750. //========================================================================================
  751. //    class CAllShapeIterator
  752. //========================================================================================
  753.  
  754. FW_DEFINE_AUTO(CAllShapeIterator)
  755.  
  756. //----------------------------------------------------------------------------------------
  757. //    CAllShapeIterator::CAllShapeIterator
  758. //----------------------------------------------------------------------------------------
  759.  
  760. CAllShapeIterator::CAllShapeIterator(CShapeCollection* shapeList) :
  761.     fIter(NULL),
  762.     fTempList(NULL)
  763. {
  764.     fTempList = FW_NEW(CShapeCollection, ());
  765.     PrivFlattenList(shapeList);
  766.     fIter = FW_NEW(CShapeCollectionIterator, (fTempList));
  767.     FW_END_CONSTRUCTOR    
  768. }
  769.  
  770. //----------------------------------------------------------------------------------------
  771. //    CAllShapeIterator::CAllShapeIterator
  772. //----------------------------------------------------------------------------------------
  773.  
  774. CAllShapeIterator::CAllShapeIterator(CDrawContent* content) :
  775.     fIter(NULL),
  776.     fTempList(NULL)
  777. {
  778.     fTempList = FW_NEW(CShapeCollection, ());
  779.     PrivFlattenList(content->fShapeList);
  780.     fIter = FW_NEW(CShapeCollectionIterator, (fTempList));
  781.     FW_END_CONSTRUCTOR    
  782. }
  783.  
  784. //----------------------------------------------------------------------------------------
  785. //    CAllShapeIterator::CAllShapeIterator
  786. //----------------------------------------------------------------------------------------
  787.  
  788. CAllShapeIterator::~CAllShapeIterator()
  789. {
  790.     FW_START_DESTRUCTOR
  791.     delete fTempList;
  792.     delete fIter;
  793. }
  794.  
  795. //----------------------------------------------------------------------------------------
  796. //    CAllShapeIterator::First
  797. //----------------------------------------------------------------------------------------
  798.  
  799. CBaseShape* CAllShapeIterator::First()
  800. {
  801.     return fIter->First();
  802. }
  803.  
  804. //----------------------------------------------------------------------------------------
  805. //    CAllShapeIterator::Next
  806. //----------------------------------------------------------------------------------------
  807.  
  808. CBaseShape*    CAllShapeIterator::Next()
  809. {
  810.     return fIter->Next();
  811. }
  812.  
  813. //----------------------------------------------------------------------------------------
  814. //    CAllShapeIterator::IsNotComplete
  815. //----------------------------------------------------------------------------------------
  816.  
  817. FW_Boolean CAllShapeIterator::IsNotComplete()
  818. {
  819.     return fIter->IsNotComplete();
  820. }
  821.  
  822. //----------------------------------------------------------------------------------------
  823. //    CAllShapeIterator::Last
  824. //----------------------------------------------------------------------------------------
  825.  
  826. CBaseShape* CAllShapeIterator::Last()
  827. {
  828.     return fIter->Last();
  829. }
  830.  
  831. //----------------------------------------------------------------------------------------
  832. //    CAllShapeIterator::Previous
  833. //----------------------------------------------------------------------------------------
  834.  
  835. CBaseShape*    CAllShapeIterator::Previous()
  836. {
  837.     return fIter->Previous();
  838. }
  839.  
  840. //----------------------------------------------------------------------------------------
  841. //    CAllShapeIterator::PrivFlattenList
  842. //----------------------------------------------------------------------------------------
  843.  
  844. void CAllShapeIterator::PrivFlattenList(CShapeCollection* shapeList)
  845. {
  846.     CShapeCollectionIterator it(shapeList);
  847.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  848.     {
  849.         if (shape->GetShapeType() == kGroupShape)
  850.             PrivFlattenList(((CGroupShape*)shape)->GetShapeList());
  851.         else
  852.             fTempList->AddLast(shape);
  853.     }
  854. }
  855.  
  856. //----------------------------------------------------------------------------------------
  857. //    CAllShapeIterator::CountShapes
  858. //----------------------------------------------------------------------------------------
  859.  
  860. unsigned long CAllShapeIterator::CountShapes()
  861. {
  862.     return fTempList->Count();
  863. }
  864.